import json

from django.http import JsonResponse
from django.views import View

from .serializers import Student1Serializer_two, Student1Serializer_one, StudentModelSerializer
from stuapi.models import Student


class StudentView1(View):
    """序列化器"""

    def get_two(self, request):
        """序列化器:序列化器的调用，多个模型对象"""
        # 1、获取数据集
        student_list = Student.objects.all()
        # 2、实例化序列化器，得到序列化对象，如果要序列化多个需要many为true
        serializer = Student1Serializer_one(instance=student_list, many=True)
        # 3、调用序列化对象的data方法转换后的数据
        data = serializer.data
        # 4、响应数据给客户端
        return JsonResponse(data=data, status=200, safe=False, json_dumps_params={
            "ensure_ascii": False})  # safe 如果返回的不是json而是list则为True，有中文反会的时候需要格式化一下 json_dumps_params={"ensure_ascii": False}一般不用

    def get_one(self, request):
        """序列化，序列化调用，序列化一个模型对象"""
        # 1、获取数据集
        student = Student.objects.filter(pk=6).values()
        # 2、实例化序列化器，得到序列化对象,如果序列化为多个many必须等于True
        serializer = Student1Serializer_one(instance=student, many=True)
        # 3、调用序列化对象的data方法转换后的数据
        data = serializer.data
        # 4、响应数据给客户端
        return JsonResponse(data=data, status=200, safe=False, json_dumps_params={
            "ensure_ascii": False})

    def get_three(self, request):
        """反序列化，采用字段选项来验证数据"""
        # 1、接收客户端提交的数据
        # data = json.dumps(request.body)
        data = {
            "name": "xiaohong",
            "age": 29,
            "sex": True,
            "description": "description111"
        }
        # 1.1 验证数据，实例化序列器
        serializer = Student1Serializer_two(data=data)
        # 1.2 调用序列化器进行数据验证
        # ret = serializer.is_valid() # 验证失败，默认不抛异常
        ret = serializer.is_valid(raise_exception=True)  # 抛出异常，代码不会往下执行
        print(ret)
        # 1.3 获取验证后的结果
        if ret:
            return JsonResponse(dict(serializer.validated_data))
        else:
            print(serializer.errors)
            return JsonResponse(dict(serializer.errors))
        # 2、操作数据库

        # 3、返回数据
        # return JsonResponse({})

    # def get(self, request):
    #     pass

    def get_four(self, request):
        """反序列化，添加数据"""
        data = {
            "name": "xiaohong",
            "age": 29,
            "sex": True,
            "description": "description111"
        }
        # 1.1 验证数据，实例化序列器
        serializer = Student1Serializer_two(data=data)
        # 1.2 调用序列化器进行数据验证
        serializer.is_valid(raise_exception=True)  # 抛出异常，代码不会往下执行
        # 1.3 获取验证后的结果
        print(serializer.validated_data)  # 这里不允许再继续访问 serializer.data数据
        # data = serializer.validated_data
        # print(data)
        # 2、操作数据库
        serializer.save()  # 会根据实例化序列化器的时候，是否传入instance属性来决定调用的create或者update方法，传入instance属性，会自动调用update方法，如果没有传入则会自动调用create
        # student = Student.objects.create(**data)
        # serializer = Student1Serializer_two(instance=student)

        # 3、 返回结果
        return JsonResponse(serializer.data, status=201)

    def get_five(self, request):
        """反序列化，修改数据"""
        # 1、根据客户端访问的url地址中，获取id值
        # sers/students/2 path("/students/(?P<id>)\d+/$")
        pk = 11
        try:
            student = Student.objects.get(pk=pk)
        except Student.DoesNotExist:
            return JsonResponse({"error": "当前学生不存在"}, status=400)

        # 2、 接收客户端提交的修改数据
        data = {
            "name": "xiaonan",
            "age": 11,
            "sex": False,
            "description": "description222"
        }
        # 3、修改操作实例化序列器对象
        serializer = Student1Serializer_two(instance=student, data=data)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # serializer = Student1Serializer_two(instance=student, data=data)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # 4、验证对象
        serializer.is_valid(raise_exception=True)
        # 5、保存入库
        serializer.save()  # save中可以传参，传递一些不需要验证的数据在模型里面
        # 6、返回结果
        return JsonResponse(serializer.data, status=201)

    def get(self, request):
        """反序列化，修改数据"""
        # 1、根据客户端访问的url地址中，获取id值
        # sers/students/2 path("/students/(?P<id>)\d+/$")
        pk = 11
        try:
            student = Student.objects.get(pk=pk)
        except Student.DoesNotExist:
            return JsonResponse({"error": "当前学生不存在"}, status=400)

        # 2、 接收客户端提交的修改数据
        data = {
            "name": "xiaonan",
            "age": 11,
            # "sex": False,
            # "description": "description222"
        }
        # 3、修改操作实例化序列器对象
        serializer = Student1Serializer_two(instance=student, data=data,
                                            partial=True)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # serializer = Student1Serializer_two(instance=student, data=data)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # 4、验证对象
        serializer.is_valid(raise_exception=True)
        # 5、保存入库
        serializer.save()  # save中可以传参，传递一些不需要验证的数据在模型里面
        # 6、返回结果
        return JsonResponse(serializer.data, status=201)


class StudentView(View):
    """模型序列化器序列化器"""

    def get2(self, request):
        """序列化器:序列化器的调用，多个模型对象"""
        # 1、获取数据集
        student_list = Student.objects.all()
        student_list.nickanme = "小学僧"
        # 2、实例化序列化器，得到序列化对象，如果要序列化多个需要many为true
        serializer = StudentModelSerializer(instance=student_list, many=True)
        # 3、调用序列化对象的data方法转换后的数据
        data = serializer.data
        # 4、响应数据给客户端
        return JsonResponse(data=data, status=200, safe=False, json_dumps_params={
            "ensure_ascii": False})  # safe 如果返回的不是json而是list则为True，有中文反会的时候需要格式化一下 json_dumps_params={"ensure_ascii": False}一般不用

    def get3(self, request):
        """序列化，序列化调用，序列化一个模型对象"""
        # 1、获取数据集
        student = Student.objects.filter(pk=6)
        for key in student.values():
            key.update({"nickname": "小学僧"})

        # 2、实例化序列化器，得到序列化对象,如果序列化为多个many必须等于True
        serializer = StudentModelSerializer(instance=student, many=True)
        # 3、调用序列化对象的data方法转换后的数据
        data = serializer.data
        # 4、响应数据给客户端
        return JsonResponse(data=data, status=200, safe=False, json_dumps_params={
            "ensure_ascii": False})

    def get4(self, request):
        """反序列化，采用字段选项来验证数据"""
        # 1、接收客户端提交的数据
        # data = json.dumps(request.body)
        data = {
            "name": "xiaohong",
            "age": 29,
            "sex": True,
            "classmate": 394,
            "description": "description111"

        }
        # 1.1 验证数据，实例化序列器
        serializer = StudentModelSerializer(data=data)
        # 1.2 调用序列化器进行数据验证
        # ret = serializer.is_valid() # 验证失败，默认不抛异常
        ret = serializer.is_valid()  # 抛出异常，代码不会往下执行
        # 1.3 获取验证后的结果
        if ret:
            return JsonResponse(dict(serializer.validated_data))
        else:
            print(serializer.errors)
            return JsonResponse(dict(serializer.errors))

    def get(self, request):
        """反序列化，添加数据"""
        data = {
            "name": "xiaohong",
            "age": 28,
            "sex": True,
            "classmate": 394,
            "description": "description111"
        }
        # 1.1 验证数据，实例化序列器
        serializer = StudentModelSerializer(data=data)
        # 1.2 调用序列化器进行数据验证
        serializer.is_valid(raise_exception=True)  # 抛出异常，代码不会往下执行
        # 1.3 获取验证后的结果
        print(serializer.validated_data)  # 这里不允许再继续访问 serializer.data数据
        # 2、操作数据库
        serializer.save()  # 会根据实例化序列化器的时候，是否传入instance属性来决定调用的create或者update方法，传入instance属性，会自动调用update方法，如果没有传入则会自动调用create
        return JsonResponse(serializer.data, status=201)

    def get7(self, request):
        """反序列化，修改数据"""
        # 1、根据客户端访问的url地址中，获取id值
        # sers/students/2 path("/students/(?P<id>)\d+/$")
        pk = 11
        try:
            student = Student.objects.get(pk=pk)
        except Student.DoesNotExist:
            return JsonResponse({"error": "当前学生不存在"}, status=400)

        # 2、 接收客户端提交的修改数据
        data = {
            "name": "xiaonan33333",
            "age": 11,
            "sex": False,
            # "classmate": 394,
            "description": "description222"
        }
        # 3、修改操作实例化序列器对象
        serializer = StudentModelSerializer(instance=student, data=data)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # 4、验证对象
        serializer.is_valid(raise_exception=True)
        # 5、保存入库
        serializer.save()  # save中可以传参，传递一些不需要验证的数据在模型里面
        # 6、返回结果
        return JsonResponse(serializer.data, status=201)

    def get1(self, request):
        """反序列化，修改数据"""
        # 1、根据客户端访问的url地址中，获取id值
        # sers/students/2 path("/students/(?P<id>)\d+/$")
        pk = 11
        try:
            student = Student.objects.get(pk=pk)
        except Student.DoesNotExist:
            return JsonResponse({"error": "当前学生不存在"}, status=400)

        # 2、 接收客户端提交的修改数据
        data = {
            "name": "xiaonan",
            "age": 11,
            # "sex": False,
            # "description": "description222"
        }
        # 3、修改操作实例化序列器对象
        serializer = Student1Serializer_two(instance=student, data=data,
                                            partial=True)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # serializer = Student1Serializer_two(instance=student, data=data)  # 修改需要传递两个参数,,partial=True 允许部分数据校验
        # 4、验证对象
        serializer.is_valid(raise_exception=True)
        # 5、保存入库
        serializer.save()  # save中可以传参，传递一些不需要验证的数据在模型里面
        # 6、返回结果
        return JsonResponse(serializer.data, status=201)
